home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / wi_libt.com / WI.DOC < prev    next >
Encoding:
Text File  |  1991-05-26  |  23.9 KB  |  643 lines

  1. -------------------------[ WI.LIB ]----------for DOS & Turbo C-----------------
  2.                       WI.LIB - Wilkes Index Library
  3.                     Copyright (c) 1991 by Roger Wilkes
  4.            Member: Association of Shareware Professionals (ASP)
  5.                   Cost of this Software $40; Gov./Ed. $30
  6.                         Wilkes Software, inc.
  7.                         Memphis, TN 38134
  8.                     or Register on BBS at (901)377-5608
  9. -------------------------------------------------------------------------------
  10.  
  11.     There are a total of six (6) function calls available with this library.
  12. 1) IX_add        - to add keys to an index file
  13. 2) IX_del        - to delete keys from an index file
  14. 3) IX_find_first - to find the first key which meets comparison criteria
  15. 4) IX_find_last  - to find the last key which meets comparison criteria
  16. 5) IX_find_next  - to find the next key
  17. 6) IX_find_prev  - to find the previous key
  18.  
  19. -------------------------------------------------------------------------------
  20.  
  21.     You must insure that "WI.LIB" is available to the linker at link time.
  22. WI.LIB is to be linked with Turbo C's large (-ml) memory model.
  23.  
  24.     Place WI.LIB in your LIB directory and place INDEX.H in your INCLUDE
  25. directory.
  26.  
  27.     The maximum char array key length is 127.  All data types other than this
  28. one can use the "data_type" defines (see INDEX.H).  The character array
  29. data type is formed by anding the length and 0x80.
  30.  
  31. -------------------------------------------------------------------------------
  32.  
  33. 1) Adding a new key to the index file:
  34.    Indexing/Reindexing a file:
  35.  
  36.     int IX_add (long            file_pos,
  37.                 char            *key_addr,
  38.                 unsigned char   data_type,
  39.                 int             file_handle);
  40.  
  41.     file_pos      - is the piece of data which will accompany the key.  This
  42.                     information will be returned to you when you use the
  43.                     IX_find_xxxxx function calls.  If you are working with
  44.                     fixed length records this can be a record length.  If you
  45.                     use this field to contain a record number, you will have
  46.                     to do multiplications to get it to a byte position within
  47.                     the file you are indexing.  You may simply use this field
  48.                     to contain the byte position of the record being indexed.
  49.     key_addr      - contains the address of either
  50.                     1) the key data
  51.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  52.                        10 key parts.  The order of importance of the key
  53.                        fields is from lowest index to highest (i.e.
  54.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  55.     data_type     - specifies that the "key_value" above is either key data
  56.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  57.                     designates key data, the length (in bytes) is also known.
  58.  
  59.     RETURNS:    One of the function returns shown in INDEX.H
  60.                     OK          where no errors were detected
  61.                     IX_IO_ERR
  62.                     IX_ERR
  63.                     INV_PARAM
  64.                     INV_NUM_KEYS
  65.  
  66.     EXAMPLE:    if we have a file with the following record layout which we
  67.                 wish to index on the last_name
  68.  
  69. -------------------------------------------------------------------------------
  70.     /* using the Borland Turbo C++ compiler */
  71. #include <index.h>      /* after placing in include dir */
  72. #include <fcntl.h>
  73. #include <sys\stat.h>
  74. #include <io.h>
  75. #include <stdlib.h>
  76. #include <stdio.h>
  77.  
  78. #define TRUE        1
  79. #define FALSE       0
  80.  
  81. int nad_file;
  82. int index_file;
  83.  
  84. int num_bytes;
  85. int err;
  86. long file_pos = 0L;
  87.  
  88. struct {
  89.     char        first_name [15];
  90.     char        last_name [15];
  91.     char        addr [30];
  92.     char        city [20];
  93.     char        state [2];
  94.     char        zip [9];
  95. } name_and_addr;
  96.  
  97. main ()
  98. {
  99.     if ((nad_file = open ("nameaddr.fil", O_CREAT | O_BINARY | O_RDWR,
  100.                           S_IREAD | S_IWRITE)) < 0)
  101.     {
  102.        /* do something about the error */
  103.     }
  104.     if ((index_file = open ("nameaddr.inx", O_CREAT | O_BINARY | O_RDWR,
  105.                            S_IREAD | S_IWRITE)) < 0)
  106.     {
  107.       /* do something about the error */
  108.     }
  109.     while (TRUE)
  110.     {
  111.         num_bytes = read (nad_file, (char *)&name_and_addr,
  112.                           sizeof(name_and_addr));
  113.         if (num_bytes == 0)     /* end of file */
  114.             break;
  115.         if (num_bytes != sizeof(name_and_addr))
  116.         {
  117.            /* take care of short read */
  118.         }
  119.         err = IX_add (file_pos, name_and_addr.last_name,
  120.                       sizeof(name_and_addr.last_name)+0x80, index_file);
  121.                    /* 0x80 is simply the high order bit
  122.                       of the data_type.  For all other data
  123.                       types you can use the #define names
  124.                       (see INDEX.H) */
  125.         switch (err)
  126.         {
  127.             case OK:
  128.                 printf ("NAME: %15.15s indexed\n",
  129.                         name_and_addr.last_name);
  130.                 break;
  131.             case IX_IO_ERR:
  132.                 printf ("IO Error on \"nameaddr.inx\" file\n");
  133.                 break;
  134.             case IX_ERR:
  135.                 printf ("Index File is corrupted\n");
  136.                 break;
  137.             case INV_PARAM:
  138.                 printf ("Function Call Parameters don't match\n");
  139.                 printf (" information already in \"nameaddr.inx\"\n");
  140.                 break;
  141.             case INV_NUM_KEYS:
  142.                 printf ("The number of key fields does not match\n");
  143.                 printf (" information already in \"nameaddr.inx\"\n");
  144.                 break;
  145.             default: break;
  146.         }
  147.         if (err)
  148.             break;
  149.         file_pos += sizeof(name_and_addr);
  150.     }
  151. }
  152. -------------------------------------------------------------------------------
  153.  
  154. 2) Deleting an index entry from an index file:
  155.  
  156.     int IX_del (char            *key_addr,
  157.                 long            file_pos,
  158.                 unsigned char   data_type,
  159.                 int             file_handle);
  160.  
  161.     key_addr      - contains the address of either
  162.                     1) the key data
  163.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  164.                        10 key parts.  The order of importance of the key
  165.                        fields is from lowest index to highest (i.e.
  166.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  167.     file_pos      - is the piece of data which will accompany the key.  This
  168.                     information will be returned to you when you use the
  169.                     IX_find_xxxxx function calls.  If you are working with
  170.                     fixed length records this can be a record length.  If you
  171.                     use this field to contain a record number, you will have
  172.                     to do multiplications to get it to a byte position within
  173.                     the file you are indexing.  You may simply use this field
  174.                     to contain the byte position of the record being indexed.
  175.                     The file position field is required in the delete to
  176.                     differentiate between duplicate keys and must be the same
  177.                     as used during IX_add.
  178.     data_type     - specifies that the "key_value" above is either key data
  179.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  180.                     designates key data, the length (in bytes) is also known.
  181.  
  182.     RETURNS:    One of the function returns shown in INDEX.H
  183.                     OK          where no errors were detected
  184.                     IX_IO_ERR
  185.                     IX_ERR
  186.                     INV_PARAM
  187.                     INV_NUM_KEYS
  188.  
  189.     EXAMPLE:    if we have a file with the following record layout which we
  190.                 wish to delete all indexes from.  NOTE: we could accomplish
  191.                 the same thing, in this case, by deleting the file; except
  192.                 here, the file size will not change (i.e. not be clean).
  193.  
  194. -------------------------------------------------------------------------------
  195.     /* using the Borland Turbo C++ compiler */
  196. #include <index.h>      /* after placing in include dir */
  197. #include <fcntl.h>
  198. #include <sys\stat.h>
  199. #include <io.h>
  200. #include <stdlib.h>
  201. #include <stdio.h>
  202.  
  203. #define TRUE        1
  204. #define FALSE       0
  205.  
  206. int nad_file;
  207. int index_file;
  208.  
  209. int num_bytes;
  210. int err;
  211. long file_pos = 0L;
  212.  
  213. struct {
  214.     char        first_name [15];
  215.     char        last_name [15];
  216.     char        addr [30];
  217.     char        city [20];
  218.     char        state [2];
  219.     char        zip [9];
  220. } name_and_addr;
  221.  
  222. main ()
  223. {
  224.     if ((nad_file = open ("nameaddr.fil", O_CREAT | O_BINARY | O_RDWR,
  225.                           S_IREAD | S_IWRITE)) < 0)
  226.     {
  227.        /* do something about the error */
  228.     }
  229.     if ((index_file = open ("nameaddr.inx", O_CREAT | O_BINARY | O_RDWR,
  230.                             S_IREAD | S_IWRITE)) < 0)
  231.     {
  232.       /* do something about the error */
  233.     }
  234.     while (TRUE)
  235.     {
  236.         num_bytes = read (nad_file, (char *)&name_and_addr,
  237.                           sizeof(name_and_addr));
  238.         if (num_bytes == 0)     /* end of file */
  239.             break;
  240.         if (num_bytes != sizeof(name_and_addr))
  241.         {
  242.             /* take care of short read */
  243.         }
  244.         err = IX_del (name_and_addr.last_name, file_pos,
  245.                       sizeof(name_and_addr.last_name)+0x80, index_file);
  246.                    /* 0x80 is simply the high order bit
  247.                       of the data_type.  For all other data
  248.                       types you can use the #define names
  249.                       (see INDEX.H) */
  250.         switch (err)
  251.         {
  252.         case OK:
  253.             printf ("NAME: %15.15s index Deleted\n",
  254.                     name_and_addr.last_name);
  255.             break;
  256.         case IX_IO_ERR:
  257.             printf ("IO Error on \"nameaddr.inx\" file\n");
  258.             break;
  259.         case IX_ERR:
  260.             printf ("Index File is corrupted\n");
  261.             break;
  262.         case INV_PARAM:
  263.             printf ("Function Call Parameters don't match\n");
  264.             printf (" information already in \"nameaddr.inx\"\n");
  265.             break;
  266.         case INV_NUM_KEYS:
  267.             printf ("The number of key fields does not match\n");
  268.             printf (" information already in \"nameaddr.inx\"\n");
  269.             break;
  270.         default: break;
  271.         }
  272.         if (err)
  273.             break;
  274.         file_pos += sizeof(name_and_addr);
  275.     }
  276. }
  277. -------------------------------------------------------------------------------
  278.  
  279. 3) Finding indexed keys in an index file:
  280.  
  281.     int IX_find_first (FIND_IX          *fix,
  282.                        char             *key_addr,
  283.                        int              find_condition,
  284.                        int              file_handle,
  285.                        unsigned char    data_type);
  286.  
  287.     int IX_find_last  (FIND_IX          *fix,
  288.                        char             *key_addr,
  289.                        int              find_condition,
  290.                        int              file_handle,
  291.                        unsigned char    data_type);
  292.  
  293.     int IX_next       (FIND_IX          *fix);
  294.  
  295.     int IX_prev       (FIND_IX          *fix);
  296.  
  297.     fix           - is the address of the FIND_IX structure
  298.                     typedef struct
  299.                     {
  300.                         long            data_rec;   /* returned file pos */
  301.                         long            recno[3];   /* used internally */
  302.                         int             ix[3];      /* used internally */
  303.                         unsigned char   data_type;  /* used internally */
  304.                         unsigned char   find_type;  /* used internally */
  305.                         VALUE           *val        /* used internally */
  306.                         int             fn;         /* used internally */
  307.                     } FIND_IX;
  308.                     the data_rec field contains the file position of the
  309.                     indexed file, in order to locate the proper record.
  310.     key_addr      - contains the address of either
  311.                     1) the key data
  312.                     2) a KEY_STRUCT (see INDEX.H) structure containing up to
  313.                        10 key parts.  The order of importance of the key
  314.                        fields is from lowest index to highest (i.e.
  315.                        KEY_COMPONENT.key[0] to KEY_COMPONENT.key[9]).
  316.                     You must insure that the value this address points to
  317.                     does not change between IX_find_first/IX_find_last
  318.                     calls and IX_find_next/IX_find_prev calls.
  319.     find_condition- is one of the file conditions listed in INDEX.H
  320.                     1) FIND_EQL
  321.                     2) FIND_GTR
  322.                     3) FIND_LSS
  323.                     4) FIND_NEQ
  324.                     5) FIND_GEQ
  325.                     6) FIND_LEQ
  326.     file_handle   - is the file number of the open file in which the indexes
  327.                     will be found.
  328.     data_type     - specifies that the "key_value" above is either key data
  329.                     or a KEY_STRUCT structure (see INDEX.H).  If data_type
  330.                     designates key data, the length (in bytes) is also known.
  331.  
  332.     EXAMPLE:    if we have a file with the following record layout which we
  333.                 wish find and print all records where the last name is
  334.                 greater than or equal to "Marty" - remember that upper and
  335.                 lower case are different:
  336.  
  337. -------------------------------------------------------------------------------
  338.     /* using the Borland Turbo C++ compiler */
  339. #include <index.h>      /* after placing in include dir */
  340. #include <fcntl.h>
  341. #include <sys\stat.h>
  342. #include <io.h>
  343. #include <stdlib.h>
  344. #include <stdio.h>
  345.  
  346. #define TRUE        1
  347. #define FALSE       0
  348.  
  349. int nad_file;
  350. int index_file;
  351.  
  352. int num_bytes;
  353. int err;
  354. long file_pos = 0L;
  355. FIND_IX fix;
  356. char *compare_field = "Marty          ";
  357.  
  358. struct {
  359.     char        first_name [15];
  360.     char        last_name [15];
  361.     char        addr [30];
  362.     char        city [20];
  363.     char        state [2];
  364.     char        zip [9];
  365. } name_and_addr;
  366.  
  367. main ()
  368. {
  369.     if ((nad_file = open ("nameaddr.fil", O_RDONLY | O_BINARY)) < 0)
  370.     {
  371.        /* do something about the error */
  372.     }
  373.     if ((index_file = open ("nameaddr.inx", O_RDONLY | O_BINARY)) < 0)
  374.     {
  375.        /* do something about the error */
  376.     }
  377.  
  378.     err = IX_find_first (&fix, compare_field,
  379.                          FIND_GEQ, index_file,
  380.                          sizeof(name_and_addr.last_name)+0x80);
  381.     while (TRUE)
  382.     {
  383.         switch (err)
  384.         {
  385.         case OK:
  386.             lseek (nad_file, fix.data_rec, SEEK_SET);
  387.             num_bytes = read (nad_file, (char *)&name_and_addr,
  388.                               sizeof(name_and_addr));
  389.             if (num_bytes != sizeof(name_and_addr))
  390.             {
  391.                 /* take care of short read */
  392.             }
  393.             printf ("NAME: %15.15s %15.15s | CITY/ST: %20.20s %2.2s\n",
  394.                     name_and_addr. first_name,
  395.                     name_and_addr. last_name,
  396.                     name_and_addr. city,
  397.                     name_and_addr. state);
  398.             break;
  399.         case IX_IO_ERR:
  400.             printf ("IO Error on \"nameaddr.inx\" file\n");
  401.             break;
  402.         case IX_ERR:
  403.             printf ("Index File is corrupted\n");
  404.             break;
  405.         case NOT_FOUND:
  406.             printf ("No Matching Keys Found\n");
  407.             break;
  408.         case NO_MORE:
  409.             printf ("No More Matching Keys Found\n");
  410.             break;
  411.         case INV_PARAM:
  412.             printf ("Function Call Parameters don't match\n");
  413.             printf (" information already in \"nameaddr.inx\"\n");
  414.             break;
  415.         case INV_NUM_KEYS:
  416.             printf ("The number of key fields does not match\n");
  417.             printf (" information already in \"nameaddr.inx\"\n");
  418.             break;
  419.         default: break;
  420.         }
  421.         if (err)
  422.             break;
  423.         err = IX_find_next (&fix);
  424.     }
  425. }
  426. -------------------------------------------------------------------------------
  427.  
  428. 4) Data Types:
  429.  
  430.     #define             "C"
  431.     -------             ---
  432.     ftCHAR              char
  433.     ftUCHAR             unsigned char
  434.     ftSCHAR             signed char
  435.     ftUNS_INT           unsigned int
  436.     ftINT               int
  437.     ftULONG             unsigned long
  438.     ftLONG              long
  439.     ftFLOAT             float
  440.     ftDOUBLE            double
  441.     ftH_BCD_1 - 10      -------         1 to 10 char BCD field with
  442.                                         sign at front of field
  443.     ftT_BCD_1 - 10      -------         1 to 10 char BCD field with
  444.                                         sign at end of field
  445.     ftSTRUCT            -------         multi field key where the
  446.                                         location of the fields is
  447.                                         specified in the KEY_STRUCT
  448.                                         structure (see INDEX.H)
  449. -------------------------------------------------------------------------------
  450.  
  451. 5) KEY_STRUCT structure for multi-field keys:
  452.  
  453.     typedef struct
  454.     {
  455.         unsigned char       num_keys;
  456.         struct
  457.         {
  458.             unsigned char   data_type;      /* data_type for this field */
  459.             VALUE           *val;           /* addr of this key field */
  460.         } key [10];
  461.     } KEY_STRUCT;
  462.  
  463.     If we wish to take the following record layout and index it on
  464. last_name and first_name (in that order):
  465.  
  466.     struct {
  467.         char        first_name [15];
  468.         char        last_name [15];
  469.         char        addr [30];
  470.         char        city [20];
  471.         char        state [2];
  472.         char        zip [9];
  473.     } name_and_addr;
  474.  
  475. with
  476.  
  477.     KEY_STRUCT      keys;
  478.  
  479. the keys would populated as follows:
  480.  
  481.     keys. num_keys = 2;
  482.     keys. key [0]. data_type = sizeof(name_and_addr.last_name) | 0x80;
  483.     keys. key [0]. val = (VALUE *)name_and_addr.last_name;
  484.     keys. key [1]. data_type = sizeof(name_and_addr.first_name) | 0x80;
  485.     keys. key [1]. val = (VALUE *)name_and_addr.first_name;
  486.  
  487. the key_addr parameter for the function calls would be "(char *)&keys"
  488. and the data_type parameter to the function calls would be ftSTRUCT.
  489.  
  490. NOTE: that the maximum number of key fields is 10.  This should be enough
  491.     for any reasonable purpose.  If you require more you can stack the
  492.     keys in some instances (char arrays back to back can be considered
  493.     a single field as long as the cumulative sizes are < 128 characters).
  494. -------------------------------------------------------------------------------
  495.  
  496.  
  497.  
  498.  
  499.  
  500.             LICENSE
  501.             -------
  502.  
  503.     Wilkes INDEX, version 1.0, is being distributed under the "shareware" or
  504. user supported concept.  This software is NOT free software.  The use or
  505. reproduction of this software outside of the limits specified in this license
  506. agreement is prohibited.
  507.  
  508.     Non-registered users are granted a limited license to use this software
  509. for a period not to exceed thirty days.  During this period they should test
  510. and evaluate the software to determine if it will meet their needs. The use of
  511. this software beyond this limited time period requires registration.
  512. Non-registered users are not allowed to distribute this software without the
  513. express written permission of Wilkes Software inc.  The only exceptions to this
  514. distribution restriction are SYSOPS of electronic bulletin boards and
  515. distributors of public domain and user supported software.  SYSOPS and
  516. software distributors must abide by the copying restrictions specified below.
  517.  
  518.     Registered users are granted the right to use Wilkes INDEX on only
  519. one computer at any time.  Site licensing agreements are available for
  520. businesses, corporations, and government agencies.  Registered users are also
  521. granted the right to copy and distribute Wilkes INDEX subject to the
  522. following conditions.
  523.  
  524.     Wilkes INDEX must be copied in its original unmodified form.
  525.  
  526.     All of the files must be included in the copy.
  527.  
  528.     Wilkes INDEX may not be distributed in conjunction with any other
  529.     product without the express written consent of Wilkes Software inc.
  530.  
  531.  
  532.  
  533.  
  534.                 WARRANTY
  535.                 --------
  536.  
  537.     Wilkes Software makes no warranty of any kind, express or implied,
  538. including without limitation, any warranties of merchantability and or fitness
  539. for a particular purpose.  Wilkes Software shall not be liable for any
  540. damages, whether direct, indirect, special or consequential arising from a
  541. failure of this software to operate in the manner desired by the user.
  542. Wilkes Software shall not be liable for any damage to data or property which
  543. may be caused directly or indirectly by use of the program.
  544.  
  545.     IN NO EVENT WILL Wilkes Software BE LIABLE TO YOU FOR ANY DAMAGES,
  546. INCLUDING ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL
  547. DAMAGES ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR FOR ANY
  548. CLAIM BY ANY OTHER PARTY.
  549.  
  550.  
  551.  
  552.  
  553.  
  554.             REGISTRATION FEES
  555.             -----------------
  556.  
  557. The registration fee for Wilkes INDEX, version 1.0, is only $40.00, with
  558. quantity discount for 10 or more copies: $25.00/copy.
  559.  
  560. Government and Education registration fee is only $30.00, with quantity
  561. discount for 10 or more copies: $20.00/copy.
  562.  
  563. You may fill out and return the registration page below or register on-line
  564. at (901)377-5608.
  565.  
  566. Future updates of the site license copy are provided as follows. The first
  567. update is free.   All others $15.00.
  568.  
  569. Prices are for a titled master copy and cover all charges including shipping.
  570. Licensees will be informed when updates become available and given the option
  571. to update at will.  There is NO penalty for skipping updates.
  572.  
  573.  
  574.  
  575.  
  576.  
  577.     If you should require assistance in the use of the Wilkes INDEX, you
  578. may call the WSI BBS at (901)377-5608.
  579.  
  580.     If you like this software please let me know.  If you have enhancements
  581. you would like to see in this software, please let me know those also.  If you
  582. have complaints about the way the Wilkes INDEX functions I would even like to
  583. hear those.
  584.  
  585.     The following is a registration form.  In addition to the licensing use,
  586. I will also use this information to correlate requests for additional
  587. functionality and for Wilkes Software mailing list purpose (only by Wilkes
  588. Software).  When Wilkes Software offers other software into the shareware
  589. system in the future, information will be sent to registered users of the
  590. Wilkes INDEX.  If you register a non-current version I will send the
  591. current version to you.
  592.  
  593.  
  594.  
  595. to: Wilkes Software, inc.
  596.     5231 Longwood Drive
  597.     Memphis, TN  38134
  598.  
  599.  
  600.     Name (first) ____________________  (last) ____________________
  601.  
  602.     Title    ___________________________________
  603.  
  604.     Company  ___________________________________
  605.  
  606.     Address  ___________________________________
  607.  
  608.              ___________________________________
  609.  
  610.     City     _________________________  State  ___  Zip code _______
  611.  
  612.     Where software obtained: ________________________________________
  613.  
  614.     Version of Wilkes INDEX for Turbo C++: 1.0
  615.  
  616.     System: ____________________
  617.  
  618.     DOS Version: _____
  619.  
  620.     Phone: (____) ____ - _____
  621.  
  622.     If Gov./Ed. please specify: _____________________________________
  623.  
  624. COST:
  625.  
  626.     $40/copy; 10+ copies $25/copy
  627.     Gov./Ed. $30/copy; 10+ copies $20/copy
  628.  
  629.     Tennessee Residents: sales tax is 7.75%
  630.  
  631.     # copies _________ x your price: ____________ + TN sales tax __________
  632.  
  633.         = Total _________________
  634.  
  635. METHOD OF PAYMENT:
  636.  
  637.     VISA/MASTERCARD/CHECK: __________
  638.  
  639.     V/MC account #: ___________________________  Expiration Date: _________
  640.  
  641.     Signature: __________________________________________________
  642.  
  643.